﻿// owner 蒋家伟

#pragma once

// jsdk
#include "ObjectReflectTemplate.h"
#include "IFieldReflectManager.h"

// 计算成员变量相对于class首地址的偏移
#define OFFSET(CLASSNAME, FIELD_NAME) \
    ((size_t)(&((CLASSNAME *)0)->FIELD_NAME))

// 最大的成员变量个数
#define MAX_MEMBER_COUNT 40
#define REFELECT_JOIN(x, y) x##y

// 计算当前定义变量是第几个
#define REFELECT_INDEXER(counter) ((sizeof(*counter((jsdk::Number_Index<MAX_MEMBER_COUNT>*)0)) - sizeof(*counter((void*)0))) / sizeof(char))

#define REFELECT_INCREASER(counter, name)  \
    static constexpr int name = REFELECT_INDEXER(counter); \
    static char (*counter(jsdk::Number_Index<sizeof(*counter((void*)0) ) / sizeof(char) + name + 1>*))[sizeof(*counter((void*)0)) / sizeof(char) + name + 1];

#define FIELD_INDEX(name) REFELECT_JOIN(reflect_tag_, name)

// 字段反射的类声明
// 参考文献     https://www.zhihu.com/question/62012225/answer/193960421?utm_id=0
// 参考源代码   https://github.com/yuanzhubi/reflect_struct
// 通过模版特化将入口统一，其难点在于如何计算成员变量的个数， REFELECT_INDEXER， REFELECT_INCREASER 很有技巧性
#define  FIELD_REFLECT_DECLARE(CLASSNAME) \
private:\
    using this_type = typename CLASSNAME; \
    using this_is_reflect_class = typename CLASSNAME;\
    static char (*field_counter(...))[1]; \
    template<typename T, int N = -1> \
    struct members_iterator: public jsdk::default_type_imp{ \
    }; \
    template <typename T, int N > friend struct members_iterator; \
public:\
    template<typename Func> \
    void fieldReflect_iterate(Func& func_instance) { \
        members_iterator<int, 0 >::fieldReflect_iterate(*this, func_instance); \
    } \
    template<typename Func> \
    bool fieldSerialize_iterate(Func& func_instance) const{ \
        return members_iterator<int, 0 >::fieldSerialize_iterate(*this, func_instance); \
    } \
    jsdk::IFieldReflectManager* getFieldReflectManager();\
    const jsdk::IFieldReflectManager* getFieldReflectManager() const;


// 字段反射字段声明
#define FIELD_REFLECT_REGISTER(FIELD_TYPE , FIELD_NAME) \
REFELECT_INCREASER(field_counter, FIELD_INDEX(FIELD_NAME))\
template<typename T>\
struct members_iterator<T, FIELD_INDEX(FIELD_NAME) > { \
    using next_type = typename members_iterator<T, FIELD_INDEX(FIELD_NAME) + 1 >;\
    template<typename Func> \
    static void fieldReflect_iterate(this_type& this_instance, Func& func_instance){ \
            func_instance(this_instance.FIELD_NAME, OFFSET(this_type, FIELD_NAME), this_instance.getFieldReflectManager(), WSTRING_OF(FIELD_TYPE), WSTRING_OF(FIELD_NAME)); \
        /*if(jsdk::is_reflect_class<FIELD_TYPE>::value){ \
            using adapter_type = typename const jsdk::reflect_class_adapter<FIELD_TYPE>::type*;\
            (static_cast<adapter_type>((void*)&this_instance))->iterate_all(func_instance); \
            } \*/\
            next_type::fieldReflect_iterate(this_instance, func_instance); \
        }; \
    template<typename Func> \
    static bool fieldSerialize_iterate(const this_type& this_instance, Func& func_instance){ \
            if(const IFieldReflectManager* pFieldReflectManager = this_instance.getFieldReflectManager())\
            {\
                if (!func_instance(this_instance.FIELD_NAME, *(pFieldReflectManager->getFieldDescriptor(WSTRING_OF(FIELD_NAME)))))\
                {\
                    return false; \
                }\
                return next_type::fieldSerialize_iterate(this_instance, func_instance); \
            }\
            return false;\
        }; \
};

